//
// Copyright (c) 2008 Nitobi Software Inc (alexei.white@nitobi.com)
// http://www.nitobi.com
//
// For questions or suggestions email Alexei White directly.
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

/*
 * Some debug tools for non-firefox browsers.
 */
try {
if (nitobi) {} else {
	nitobi = {};
	};} catch(e) { nitobi = {};}

nitobi.Debug = {
	
	ver: 1.0,
	
	initialized: false,
	
	top: 20,
	
	left: 20,
	
	lastMouseX: 0,
	
	lastMouseY: 0,
	
	tdiff : 0,
	
	ldiff : 0,
	
	width: 500,
	
	height: 150,
	
	originalwidth: 500,
	
	originalheight: 80,
	
	textstyle: "font-family: Courier New, courier, verdana; font-size: 12px;",
	
	init: function() {
		rb = nitobi.Debug;
		rb.xpath = !!(document.evaluate);
		if (window.ActiveXObject) rb.ie = window[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
		else if (document.childNodes && !document.all && !navigator.taintEnabled) rb.webkit = rb[rb.xpath ? 'webkit420' : 'webkit419'] = true;
		else if (document.getBoxObjectFor != null) rb.gecko = true;
		
		/*compatibility*/
		
		rb.khtml = rb.webkit;
		
		this.isStandards = false;
		if (nitobi.Debug.ie) {
			if (document.compatMode == "CSS1Compat")
				this.isStandards = true;
		} else {
			if (document.doctype) this.isStandards = true;
		};
				
		this.attachWindowEvent('mousemove', nitobi.Debug.mouseMove); // Attach the mousemove event
				
		if (nitobi.Debug.getCookie("nitobi_debug_top") != null) {
			this.top = parseInt(nitobi.Debug.getCookie("nitobi_debug_top"));
			this.left = parseInt(nitobi.Debug.getCookie("nitobi_debug_left"));
		}
		if (nitobi.Debug.getCookie("nitobi_debug_width") != null) {
			this.width = parseInt(nitobi.Debug.getCookie("nitobi_debug_width"));
			this.height = parseInt(nitobi.Debug.getCookie("nitobi_debug_height"));
		}		
		if (this.initialized == false)

		    var scr = document.createElement('div');
			scr.style.position = 'absolute';
			scr.style.left = this.left + 'px';scr.style.top = this.top + 'px';
			scr.style.width = this.width + 'px';scr.style.height = this.height+'px';
			scr.style.padding = '0px'; scr.style.margin = '0px';
			scr.style.overflow = 'hidden';
			scr.style.visibility = 'visible'; scr.style.display = 'block';
			scr.style.zIndex = '1';
			scr.style.backgroundColor = 'white';
			scr.style.border = '1px solid blue';	
			scr.id = "nitobi_debug_window";
			scr.innerHTML = "<div style=\"position:relative;\"><button id=\"nitobi_debug_clear\" onclick=\"nitobi.Debug.clearLog();\" style=\"font-size:8px; font-weight:bold; position:absolute; width:20px; height:20px; top:0px; left:" + (this.width-25) + "px;\">c</button><button id=\"nitobi_debug_close\" onclick=\"document.getElementById('nitobi_debug_window').style.display = 'none';\" style=\"font-size:8px; font-weight:bold; position:absolute; width:20px; height:20px; top:0px; left:" + (this.width-25) + "px;\">x</button><div id=\"nitobi_debug_header\" onselectstart=\"return false;\" ondragover=\"return false\" ondragenter=\"return false\"onmousedown=\"nitobi.Debug.startDrag()\" style=\"background-color:blue; width: " + this.width + "px; color:white; font-family:verdana; font-size:10px; font-weight:bold; padding:3px; cursor:move\">nitobi debug window</div><div id=\"nitobi_debug_grabby\" style=\"position:absolute; top:10px;left:10px;width:16px; height:8px; cursor:se-resize; display:block; background-color: blue; padding:0px; margin:0px;\" onselectstart=\"return false;\" ondragover=\"return false\" ondragenter=\"return false\"onmousedown=\"nitobi.Debug.startCornerDrag()\"></div><div id=\"nitobi_debug_contents\" style=\"border:1px solid white; " + this.textstyle + " overflow:scroll;\"></div><table width=\"100%\" cellpadding=0 cellspacing=0 id=\"nitobi_debug_codeentryt\"><tr id=\"nitobi_debug_trce\"><td id=\"nitobi_debug_cetrd\"><form name=\"nitobi_debug_ceform\" id=\"nitobi_debug_ceform\" style=\"margin:0px;padding:0px;\"><textarea onkeydown=\"return nitobi.Debug.handleKeyPress(event)\" name=\"nitobi_debug_code_entry\" id=\"nitobi_debug_code_entry\" style=\"width:100%; height:40px;\"></textarea></form></td></tr></table><button id=\"nitobi_debug_btncode\" style=\"width:20px;height:20px;position:absolute;top:10px;left:10px;font-family:verdana, arial; font-size:20px; font-weight:bold;\" onclick=\"nitobi.Debug.evaltbCode()\" >!</button></div>";
			document.body.appendChild(scr);		
			this.positionGrabby();	
			
		this.initialized = true;
	},
	
	mouseMove: function(event) {
		var sg = nitobi.Debug.getScrollPosition();

		var mouse = {};
		mouse.clientX = event.clientX + sg.scrollLeft;
		mouse.clientY = event.clientY + sg.scrollTop;
		nitobi.Debug.lastMouseCoords = mouse;

		
	},
	
	lastHandleKeyPress: new Date(),
	
	handleKeyPress: function(event) {
		var myf = document.forms["nitobi_debug_ceform"];
		var mycode = myf.nitobi_debug_code_entry.value;
		rd = nitobi.Debug;
		var nnow = new Date();
		
		if ((rd.codeExecHistory.length > 0) && ((mycode.length < 1) || ((nnow - rd.lastHandleKeyPress)<1000)) && (event.keyCode == 38)) {
			myf.nitobi_debug_code_entry.value = rd.codeExecHistory[rd.codeExecHistory.length-1];
			rd.codeExecHistory.length -= 1;
			rd.lastHandleKeyPress = new Date();
		}
		//nitobi.Debug.log(event);
	},
	
	startDrag: function() {
		document.onselectstart=new Function ("return false");
		if (this.lastMouseCoords.clientX) {
			nitobi.Debug.lastMouseX = this.lastMouseCoords.clientX;
			nitobi.Debug.lastMouseY = this.lastMouseCoords.clientY;				
		}
		nitobi.Debug.attachWindowEvent('mousemove', nitobi.Debug.moveDebugWindow);
		nitobi.Debug.attachWindowEvent('mouseup', nitobi.Debug.endDrag);
		nitobi.Debug.tdiff = nitobi.Debug.lastMouseY-nitobi.Debug.top;
		nitobi.Debug.ldiff = nitobi.Debug.lastMouseX-nitobi.Debug.left;
	},
	
	
	endDrag: function() {
		document.onselectstart=new Function ("");
		nitobi.Debug.removeWindowEvent('mousemove', nitobi.Debug.moveDebugWindow);
		nitobi.Debug.removeWindowEvent('mouseup', nitobi.Debug.endDrag);		
		nitobi.Debug.setCookie("nitobi_debug_top", nitobi.Debug.top);
		nitobi.Debug.setCookie("nitobi_debug_left", nitobi.Debug.left);		
	},
	
	moveDebugWindow: function(event) {
		var mouse = {};
		var sg = nitobi.Debug.getScrollPosition();
		mouse.clientX = event.clientX + sg.scrollLeft;
		mouse.clientY = event.clientY + sg.scrollTop;
		
		// Now see if we are in an iFrame
		var myC = {x:0, y:0};
		var myEl = (event.srcElement || event.currentTarget);
		myC = nitobi.Debug.getiFrameCoords(myEl); // Put any iFrame offsets into here
		
		// Now we check to see if we have to work iFrame calculations into the mix
			
		if ((myC.x>0) || (myC.y>0)) {
			// Yes there was iFrame stuff.. now reintegrate the data into the mouse coords
			myC.x += event.clientX;
			myC.y += event.clientY;
			mouse.clientX = myC.x;
			mouse.clientY = myC.y;
		}		
		var mx = mouse.clientX;
		var my = mouse.clientY;                            
		var dw = document.getElementById('nitobi_debug_window');
		nitobi.Debug.top = my-nitobi.Debug.tdiff;
		nitobi.Debug.left = mx-nitobi.Debug.ldiff;
		nitobi.Debug.lastMouseX = mouse.clientX;
		nitobi.Debug.lastMouseY = mouse.clientY;
		dw.style.left = nitobi.Debug.left + 'px';
		dw.style.top = nitobi.Debug.top + 'px';
	},
	
	codeExecHistory: Array(),
	
	evaltbCode: function() {

		var myf = document.forms["nitobi_debug_ceform"];
		var mycode = myf.nitobi_debug_code_entry.value;	
		rd = nitobi.Debug;
		rd.codeExecHistory[rd.codeExecHistory.length] = mycode;
		myf.nitobi_debug_code_entry.value = "";
		try{rec = eval(mycode);
		rd.log(rec);
		} catch(e) {rec = e;
		rd.log(rec, "#fff0f0");};
		
		
	},
	
	positionGrabby: function() {
		var dg = document.getElementById('nitobi_debug_grabby');
		var dw = document.getElementById('nitobi_debug_window');
		var dh = document.getElementById('nitobi_debug_header');		
		var dc = document.getElementById('nitobi_debug_contents');		
		var ce = document.getElementById('nitobi_debug_codeentryt');	
		var btn = document.getElementById('nitobi_debug_btncode');
		var cbtn = document.getElementById('nitobi_debug_clear');
		var xbtn = document.getElementById('nitobi_debug_close');
		
		btn.style.height = ce.offsetHeight;
		btn.style.width = ce.offsetHeight;
		btn.style.top = (dw.offsetHeight-btn.offsetHeight-1) + 'px';
		btn.style.left = (dw.offsetWidth-btn.offsetWidth-dg.offsetWidth) + 'px';	
		
		cbtn.style.height = dh.offsetHeight;
		cbtn.style.width = dh.offsetHeight;
		cbtn.style.top = '0px';
		cbtn.style.left = (dw.offsetWidth-cbtn.offsetWidth-xbtn.offsetWidth) + 'px';			

		xbtn.style.height = dh.offsetHeight;
		xbtn.style.width = dh.offsetHeight;
		xbtn.style.top = '0px';
		xbtn.style.left = (dw.offsetWidth-cbtn.offsetWidth) + 'px';	
			
		dg.style.top = (dw.offsetHeight-dg.offsetHeight) + 'px';
		dg.style.left = (dw.offsetWidth-dg.offsetWidth) + 'px';
		dh.style.width = (dw.offsetWidth) + 'px';
		dc.style.height = (dw.offsetHeight-dh.offsetHeight-1-ce.offsetHeight) + 'px';
		dc.style.width = '100%';
	},
	
	
	startCornerDrag: function() {
		nitobi.Debug.originalwidth = nitobi.Debug.width;
		nitobi.Debug.originalheight = nitobi.Debug.height;		
		document.onselectstart=new Function ("return false");
		nitobi.Debug.lastMouseX = this.lastMouseCoords.clientX;
		nitobi.Debug.lastMouseY = this.lastMouseCoords.clientY;		
		nitobi.Debug.attachWindowEvent('mousemove', nitobi.Debug.moveResize);
		nitobi.Debug.attachWindowEvent('mouseup', nitobi.Debug.endCornerDrag);
		nitobi.Debug.tdiff = nitobi.Debug.lastMouseY-nitobi.Debug.top;
		nitobi.Debug.ldiff = nitobi.Debug.lastMouseX-nitobi.Debug.left;
	},
	
	
	endCornerDrag: function() {
		document.onselectstart=new Function ("");
		nitobi.Debug.removeWindowEvent('mousemove', nitobi.Debug.moveResize);
		nitobi.Debug.removeWindowEvent('mouseup', nitobi.Debug.endCornerDrag);		
		nitobi.Debug.setCookie("nitobi_debug_width", nitobi.Debug.width);
		nitobi.Debug.setCookie("nitobi_debug_height", nitobi.Debug.height);
	},
	
	moveResize: function(event) {
		var mouse = {};
		var sg = nitobi.Debug.getScrollPosition();
		mouse.clientX = event.clientX + sg.scrollLeft;
		mouse.clientY = event.clientY + sg.scrollTop;
		
		// Now see if we are in an iFrame
		var myC = {x:0, y:0};
		var myEl = (event.srcElement || event.currentTarget);
		myC = nitobi.Debug.getiFrameCoords(myEl); // Put any iFrame offsets into here
		
		// Now we check to see if we have to work iFrame calculations into the mix
			
		if ((myC.x>0) || (myC.y>0)) {
			// Yes there was iFrame stuff.. now reintegrate the data into the mouse coords
			myC.x += event.clientX;
			myC.y += event.clientY;
			mouse.clientX = myC.x;
			mouse.clientY = myC.y;
		}		
		var mx = mouse.clientX;
		var my = mouse.clientY;                            
		var dw = document.getElementById('nitobi_debug_window');
		var oh = my-nitobi.Debug.tdiff-nitobi.Debug.top;
		var ow = mx-nitobi.Debug.ldiff-nitobi.Debug.left;
		nitobi.Debug.width = nitobi.Debug.originalwidth+ow;
		nitobi.Debug.height = nitobi.Debug.originalheight+oh;
		if (nitobi.Debug.width < 200)
			nitobi.Debug.width = 200;
		if (nitobi.Debug.height < 80)
			nitobi.Debug.height = 80;			
		nitobi.Debug.lastMouseX = mouse.clientX;
		nitobi.Debug.lastMouseY = mouse.clientY;
		dw.style.width = nitobi.Debug.width + 'px';
		dw.style.height = nitobi.Debug.height + 'px';
		nitobi.Debug.positionGrabby();
	},
	
	clearLog: function() {
		nitobi.Debug.logContents = "";
		var dc = document.getElementById('nitobi_debug_contents');	
		dc.innerHTML = '';
		nitobi.Debug.configScroller();		
	},
	
	logContents: "",
	
	lastColor: "#f0f0f0",
	
	logCount: 0,
	
	log: function(vartoinspect, alertlevel) {
		
		//if (this.debugSessionID > -1) {
			
			nitobi.Debug._log(vartoinspect, alertlevel);
		//}
	},
	
	_log: function(vartoinspect, alertlevel) {
		
		if (!vartoinspect)
			vartoinspect = "";
		nitobi.Debug.logCount++;
		
		if (this.initialized == false)
			this.init();
		
		try {document.getElementById('nitobi_debug_window').style.display = 'block';} catch(e) {};

			if (!alertlevel) {
				if (nitobi.Debug.lastColor == "#f0f0f0")
					nitobi.Debug.lastColor = "transparent";
				else
					nitobi.Debug.lastColor = "#f0f0f0";				
			}
			if (alertlevel)
				nitobi.Debug.lastColor = alertlevel;
			
			var varhtml = "";
			
			var rd = nitobi.Debug;
			
			var didRender = false;

			if (vartoinspect.constructor == Array) { 			// ARRAYS *********************
				didRender = true;
				varhtml = "<span id=\"nitobi_debug_arrid_00_" + rd.logCount + "\" style=\"color: green;\">Array: [</span>";
				for (var ic = 0, b = vartoinspect.length; ic < b; ic++) {
					if (ic > 0) 
						varhtml += "<span id=\"nitobi_debug_arrid_00_" + rd.logCount + "_" + ic + "\" style=\"color: green; font-weight:bold;\">, </span>";

						varhtml += rd.escapeHTML(vartoinspect[ic]);

				}
				varhtml += "<span id=\"nitobi_debug_arrid_01_" + rd.logCount + "\" style=\"color: green;\">]</span>";
				
			} else if (vartoinspect.constructor == Object) { 	// GENERAL OBJECTS ***************
				var ic = 0;
				didRender = true;
				varhtml = "<table cellpadding=0 cellspacing=0 id=\"nitobi_debug_tabrow" + rd.logCount + "\">";

				for (var i in vartoinspect) {
					ic++;

						varhtml += "<tr id=\"nitobi_debug_tabrrow" + rd.logCount + "\"><td valign=top id=\"nitobi_debug_tabtd0_" + rd.logCount + "\" style=\"" + rd.textstyle + "; color:green;\" >" + rd.escapeHTML(i) + "</td><td valign=top style=\"padding-left: 10px; " + rd.textstyle + " \" id=\"nitobi_debug_tabtd1_" + rd.logCount + "\">" + rd.escapeHTML(vartoinspect[i]) + "</td></tr>";

				}
				varhtml += "</table>";
				
			} else if (vartoinspect.constructor == String) { 	// STRINGS ***************
					didRender = true;
					varhtml += rd.escapeHTML(vartoinspect);
					
			} else if (vartoinspect.constructor == Number) { 	// NUMBERS ***************
					didRender = true;
					varhtml += vartoinspect;
					
			} else if (vartoinspect.constructor == Boolean) { 	// BOOLEANS ***************
					didRender = true;
					varhtml += vartoinspect.toString();
					
			}		
			
			if (didRender == false ) {
				var ic = 0;
				didRender = true;
				varhtml = "<table cellpadding=0 cellspacing=0 id=\"nitobi_debug_tabrow" + rd.logCount + "\">";
				var oCoords = nitobi.Debug.getAbsoluteCoords(vartoinspect);
				var showref = nitobi.Debug.createShowMeRef(vartoinspect);
				varhtml += "<tr id=\"nitobi_debug_tabrrow" + rd.logCount + "\"><td valign=top  style=\"" + rd.textstyle + "; color:black; background-color:yellow; width:100%;\" colspan=2>DOM Coordinates <u><span id=\"showmeref_" + showref + "\" style=\"background-color: #ff00ff; cursor:pointer;\" onmouseover=\"nitobi.Debug.showitem(" + showref + ")\" onmouseout=\"nitobi.Debug.removeshowitem(" + showref + ")\">[Show me]</span></u></td></tr>";				
				for (var i in oCoords) {
					ic++;

						varhtml += "<tr id=\"nitobi_debug_tabrrow" + rd.logCount + "\"><td valign=top id=\"nitobi_debug_tabtd0_" + rd.logCount + "\" style=\"" + rd.textstyle + "; color:green;\" >" + rd.escapeHTML(i) + "</td><td valign=top style=\"padding-left: 10px; " + rd.textstyle + " \" id=\"nitobi_debug_tabtd1_" + rd.logCount + "\">" + rd.escapeHTML(oCoords[i]) + "</td></tr>";				
				};
				
				varhtml += "<tr id=\"nitobi_debug_tabrrow" + rd.logCount + "\"><td valign=top  style=\"" + rd.textstyle + "; color:black; background-color:yellow;\" colspan=2>Object Members</td></tr>";								
				
				ic = 0;	
				for (var i in vartoinspect) {
					ic++;

						varhtml += "<tr id=\"nitobi_debug_tabrrow" + rd.logCount + "\"><td valign=top id=\"nitobi_debug_tabtd0_" + rd.logCount + "\" style=\"" + rd.textstyle + "; color:green;\" >" + rd.escapeHTML(i) + "</td><td valign=top style=\"padding-left: 10px; " + rd.textstyle + " \" id=\"nitobi_debug_tabtd1_" + rd.logCount + "\">" + rd.escapeHTML(vartoinspect[i]) + "</td></tr>";

				}
				varhtml += "</table>";
			}
			var newTextBlock = document.createElement('div');
			newTextBlock.id = "nitobi_debug_div0p_" + nitobi.Debug.logCount;
			newTextBlock.innerHTML = "<div id=\"nitobi_debug_row" + nitobi.Debug.logCount + "\" style=\"width:100%; margin-bottom:1px; background-color: " + nitobi.Debug.lastColor + "\">" + varhtml + "</div>";
			nitobi.Debug.logContents += newTextBlock.innerHTML;
			var dc = document.getElementById('nitobi_debug_contents');	
			dc.appendChild(newTextBlock);
			//dc.innerHTML = nitobi.Debug.logContents + "<br><br>";
			nitobi.Debug.configScroller();
			
		
	},
	
	
	configScroller: function() {
		
		var rd = nitobi.Debug;
		clearTimeout(rd.scrollerTimer);
		var dc = document.getElementById('nitobi_debug_contents');	
		rd.scrollHeight = dc.scrollHeight-dc.offsetHeight;
		rd.scrollContents();
	},
	
	
	scrollerTimer: null,
	
	scrollTop: 0,
	
	scrollVelocity: 0,
	
	scrollHeight: 0,
		
	scrollContents: function() {
		var rd = nitobi.Debug;
		var dc = document.getElementById('nitobi_debug_contents');	
		rd.scrollHeight = dc.scrollHeight-dc.offsetHeight;		
		clearTimeout(rd.scrollerTimer);
		
		if (rd.scrollTop < rd.scrollHeight) {
			rd.scrollVelocity += 2;
		} else {
			rd.scrollVelocity = 0;
			rd.scrollTop = rd.scrollHeight+100;
		}
		
		/*if (rd.scrollVelocity > 15)
			rd.scrollVelocity = 15;
			*/
			
		rd.scrollTop += rd.scrollVelocity;
		var dc = document.getElementById('nitobi_debug_contents');
		dc.scrollTop = rd.scrollTop;
		if (rd.scrollTop < rd.scrollHeight)
			rd.scrollerTimer = setTimeout("nitobi.Debug.scrollContents()", 60);
	},
	
	escapeHTML: function(str)
	{
		if (str == null)
			str = "null";
			
		var div = document.createElement('div');
		try	{
			var text = document.createTextNode(str.toString());	
		} catch(e) {
			var text = document.createTextNode("unknown error on " + str);
		}
		
		div.appendChild(text);
		return div.innerHTML;
	},
	
	
	
	
	
	
	
	
	
	debugSessionID: -1,
	
	
	
	
	
	setupSpecialRecDebug: function(){
		if (document.body) {
			nitobi.DebugSessionId = nitobi.Debug.debugSessionID;
			var div = document.createElement('div');
			div.id = "robotreplay_debug_specialdiv";
			div.style.position = 'absolute';
			div.style.top = "1px";
			div.style.left = "1px";
			div.style.fontSize = "100px";
			div.style.color = "#cccccc";
			div.innerHTML = "Debug: " + nitobi.Debug.debugSessionID;
			document.body.appendChild(div);			
		} else {
			setTimeout("nitobi.Debug.setupSpecialRecDebug()", 500);
			
		}
	
	},
	
	
	
	/* 
	 * Detects if cookies are turned on
	 */
	cookiesOn: function() {
		this.setCookie("rr_ctest", "123", 5000);
		if (this.getCookie("rr_ctest") == "123") {
			this.delCookie("rr_ctest");
			return true;
		} else
			return false;
	},
	
	/*
	 * Handles used
	 */
	cookiesUsed: function() {
		var a = document.cookie;
		return a.split(';').length;
	},
	
	/*
	 * Set a cookie.. this will overwrite any cookies of the same name
	 * and check to see the total written size wont be bigger than the limit
	 */
	setCookie: function ( name, value, expires, path, domain, secure, skipencode ) {

		nitobi.Debug.delCookie(name);
		path = "/";
		if (!expires) expires = 600000; // 1 hour default expiration
		var expires_date = new Date( (new Date()).getTime() + (expires) );		
		if (!skipencode)
			value = (value+'');
		var cookieData = name + "=" + value +
			( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
			( ( path ) ? ";path=" + path : "" ) + 
			( ( domain ) ? ";domain=" + domain : "" ) +
			( ( secure ) ? ";secure" : "" );
		//if (((cookieData).length+document.cookie.length) < 4096) {	// 4096 bytes is the max possible size limit
		document.cookie = cookieData;
		//} else {
			//return false; // This cookie cannot be written
		//}
	},
	/*
	 * Get a cookie by name
	 */
	getCookie: function(name, skipdecode) {
		var start = document.cookie.indexOf( name + "=" );
		var len = start + name.length + 1;
		if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
			return null;
		}
		if ( start == -1 ) return null;
		var end = document.cookie.indexOf( ";", len );
		if ( end == -1 ) end = document.cookie.length;
		if (!skipdecode)
			return decodeURIComponent( document.cookie.substring( len, end ) );
		else
			return document.cookie.substring( len, end );
	},
	/*
	 * Totally eradicate a cookie by name, path, and domain (path and domain are optional)
	 */
	delCookie: function(name, path, domain ) {

		var date = new Date();
		date.setTime(date.getTime()+(-1*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
		document.cookie = name+"="+expires+"; path=/"
	},
	
	
	// This is a general event attachment thingy
	
	attach: function(obj, eventName, fnReference, direction) {
		if (!direction)
			direction = false;
		if (window.addEventListener) { 
			// Non-IE browsers
			obj.addEventListener(eventName, fnReference, direction);					
		} else if (window.attachEvent) { 
			// IE 6+
			obj.attachEvent('on' + eventName, fnReference);	
		}		
	},

	// This is a general event removal thingy
	
	remove: function(obj, eventName, fnReference, direction) {
		if (!direction)
			direction = false;		
		if (window.addEventListener) { 
			// Non-IE browsers
			obj.removeEventListener(eventName, fnReference, direction);					
		} else if (window.attachEvent) { 
			// IE 6+
			obj.detachEvent('on' + eventName, fnReference);	
		}		
	},
	
	// This function is for special 'window' events
	// like scroll and mousemove..
	// because there is some conditional stuff needed for IE
	
	attachWindowEvent: function(eventName, fnReference) {
		if (this.ie) {
			if ((eventName == "scroll") || (eventName == "resize"))
				this.attach(window, eventName, fnReference);
			else
				this.attach(document, eventName, fnReference);
		} else
			this.attach(window, eventName, fnReference);	
	},
	
	
	// This function is for special 'window' events
	// like scroll and mousemove..
	// because there is some conditional stuff needed for IE
	
	removeWindowEvent: function(eventName, fnReference) {
		if (this.ie) {
			if ((eventName == "scroll") || (eventName == "resize"))
				this.remove(window, eventName, fnReference);
			else
				this.remove(document, eventName, fnReference);
		} else
			this.remove(window, eventName, fnReference);	
	},
	
	
	// Just gets the scroll position
	
	getScrollPosition: function() {
		var scrollLeft = 0;
		var scrollTop = 0;	
		var nd = nitobi.Debug;
		var doc = nitobi.Debug.isStandards; // Is standards mode

		var db = document.body; // Shorten this for brevity
		var dd = document.documentElement; // Shorten this for brevity
		if (doc==true) {
			// Standards Mode
			if (nd.ie || nd.gecko || nd.opera) {
				// All internet explorer's
				scrollLeft = dd.scrollLeft;
				scrollTop = dd.scrollTop;
			} else if (client == "webkit") {
				scrollLeft = db.scrollLeft;
				scrollTop = db.scrollTop;				
			}
		} else {
			// Quirks Mode
			scrollLeft = db.scrollLeft;
			scrollTop = db.scrollTop;
		};			
		return {scrollLeft: scrollLeft, scrollTop: scrollTop};	
	},
	
	// This function returns the coordinates of the element within its frame ************
	
	getCoords: function(element){
	
		var ew, eh;
		var originalElement = element;
		ew = element.offsetWidth;
		eh = element.offsetHeight;
		for (var lx = 0, ly = 0; element != null; lx += element.offsetLeft, ly += element.offsetTop, element = element.offsetParent) {
		};
		for (; ((originalElement != document.body) && (originalElement.documentElement == undefined)); lx -= originalElement.scrollLeft, ly -= originalElement.scrollTop, originalElement = originalElement.parentNode) {
		};
		
		return {
			x: lx,
			y: ly,
			height: eh,
			width: ew
		}
	},
	
	// This function gives real screen coords that take into account iframe paths *********
	
	getiFrameCoords: function(element){
	
		var nd = nitobi.Debug;

		var myC = {
			x: 0,
			y: 0
		};

		if (nd.ie) {
			// IE
			var iFr = element.ownerDocument.parentWindow.window.frameElement;
			while (iFr) {
				// Yes we are in an iFrame
				var myC2 = this.getCoords(iFr);
				myC.x += myC2.x;
				myC.y += myC2.y;
				iFr = iFr.ownerDocument.parentWindow.window.frameElement;
			}
		}
		else {
			// Firefox and others
			try {
				var iFr = (element.frameElement || element.ownerDocument.defaultView.frameElement);
				} catch(e) {iFr = null;}
			
			while (iFr) {
				// Yes we are in an iFrame
				var myC2 = this.getCoords(iFr);
				myC.x += myC2.x;
				myC.y += myC2.y;
				if (iFr.ownerDocument)
					iFr = iFr.ownerDocument.defaultView.frameElement;
				else iFr = null;
			}
			
		};
				
		return myC;
		
	},
	
	// This gets the absolute page coordinates based on iframe position and relative position
	
	getAbsoluteCoords: function(myobj) {

		var ac = this.getCoords(myobj);
		var ic = this.getiFrameCoords(myobj);
		ac.y += ic.y; ac.x += ic.x;		
		
		return ac;
	},
	
	// This function gets an ID that includes its iFrame path *****************************
	
	getiFrameReference: function(frameEl){

		var resId = frameEl.id;
		if (nitobi.Debug.ie) {
			// IE
			var iFr = frameEl.ownerDocument.parentWindow.window.frameElement;
			while (iFr) {
				// Yes we are in an iFrame
				resId = iFr.id + ";" + resId;
				var iFr = iFr.ownerDocument.parentWindow.window.frameElement;
			}
		}
		else {
			// Firefox and others
			var iFr = frameEl.ownerDocument.defaultView.frameElement;
			
			while (iFr) {
				// Yes we are in an iFrame
				resId = iFr.id + ";" + resId;
				var iFr = iFr.ownerDocument.defaultView.frameElement;
			}
			
		}
		return resId;
	},
	
	
	// Create a show-me reference
	
	showmearchive: Array(),
	
	createShowMeRef: function(obj) {
		var nd = nitobi.Debug;
		var showmeid = nd.showmearchive.length;
		
		nd.showmearchive[showmeid] = obj;
		
		return showmeid;
		
	},
	
	
	
	
	// Show an item on the page
	highlightObj: null,
	
	showitem: function(itemid) {
		var nd = nitobi.Debug;
		var obj = nd.showmearchive[itemid];
		var coords = nd.getAbsoluteCoords(obj);
		nd.highlightObj = document.createElement("div");
		nd.highlightObj.style.opacity = "0.3";
		nd.highlightObj.style.filter = "alpha(opacity=30);";
		nd.highlightObj.style.backgroundColor = "#ffff00";
		nd.highlightObj.style.padding = "0px";
		nd.highlightObj.style.margin = "0px";
		nd.highlightObj.style.position = "absolute";				
		nd.highlightObj.style.left = coords.x + "px";		
		nd.highlightObj.style.top = coords.y + "px";		
		nd.highlightObj.style.width = coords.width + "px";		
		nd.highlightObj.style.height = coords.height + "px";								
		document.body.appendChild(nd.highlightObj);
		
	},
	
	removeshowitem: function(itemid) {
		var nd = nitobi.Debug;								
		document.body.removeChild(nd.highlightObj);
		
	}	
};

